﻿Imports System.Runtime.CompilerServices

''' <summary>
''' The base class of regular expressions. Provides methods to build a regular expression
''' </summary>
Public MustInherit Class RegularExpression

    Friend Sub New(ByVal expType As RegularExpressionType)
        m_expType = expType
    End Sub

    Private m_expType As RegularExpressionType
    Public ReadOnly Property ExpressionType() As RegularExpressionType
        Get
            Return m_expType
        End Get
    End Property

    ''' <summary>
    ''' Returns a regular expression represents a language that repeat this language zero or many times.
    ''' </summary>
    Public Function Repeat() As RegularExpression
        Return New KleeneStar(Me)
    End Function

    ''' <summary>
    ''' Returns a regular expression represents a language that sequence this language by another language.
    ''' </summary>
    Public Function Sequence(ByVal follow As RegularExpression) As RegularExpression
        Return New Concatenation(Me, follow)
    End Function

    ''' <summary>
    ''' Returns a regular expression accept either this language and another language
    ''' </summary>
    Public Function Union(ByVal other As RegularExpression) As RegularExpression
        If Me.Equals(other) Then Return Me
        Return New Alternation(Me, other)
    End Function

    ''' <summary>
    ''' Returns a regular expression represents a language repeat this language one or many times.
    ''' </summary>
    Public Function Repeat1() As RegularExpression
        Return Me.Sequence(Me.Repeat)
    End Function

    ''' <summary>
    ''' Returns a regular expression accept either this language or an empty char.
    ''' </summary>
    Public Function [Optional]() As RegularExpression
        Return Me.Union(Empty.Instance)
    End Function

    <SpecialName()>
    Public Shared Function op_RightShift(ByVal left As RegularExpression, ByVal right As RegularExpression) As RegularExpression
        Return New Concatenation(left, right)
    End Function

    Public Shared Operator Or(ByVal left As RegularExpression, ByVal right As RegularExpression) As RegularExpression
        Return New Alternation(left, right)
    End Operator

    Public Shared Function FromRange(ByVal min As Char, ByVal max As Char) As RegularExpression
        Return New LiteralRange(New CharRange(min, max))
    End Function

    Public Shared Function FromRange(ByVal range As CharRange) As RegularExpression
        Return New LiteralRange(range)
    End Function

    Public Shared Function FromString(ByVal str As String) As RegularExpression
        CodeContract.RequiresArgumentNotNull(str, "str")
        If str.Length = 0 Then Return Empty.Instance
        If str.Length = 1 Then Return New LiteralChar(str(0))

        'length > 1
        Dim first As New LiteralChar(str(0))
        Dim result As RegularExpression = first

        For i = 1 To str.Length - 1
            result = result.Sequence(New LiteralChar(str(i)))
        Next

        Return result
    End Function

    Public Shared Function FromChar(ByVal c As Char) As RegularExpression
        Return New LiteralChar(c)
    End Function
End Class
